#include "session.h"
#include "io_thread.h"
#include "defer.h"
#include "MsgNode.h"

HeadBuf::HeadBuf(size_t head_len) : _head_len(head_len), _offset(0) {
    _buf = std::make_unique<char[]>(_head_len + 1); // 多分配1字节以保证末尾安全
    std::memset(_buf.get(), 0, _head_len + 1);  // 初始化缓冲区为0
}

HeadBuf::~HeadBuf() {
    // 智能指针会自动释放内存，无需手动操作
}

// DataBuf类实现
DataBuf::DataBuf(uint16_t msg_type, size_t body_len)
    : _msg_type(msg_type), _total_len(body_len), _offset(0) {
    // 严格检查消息体长度，确保不超过最大限制
    if (body_len > MAX_LENGTH - HEAD_TOTAL_LEN) {
        std::cerr << "DataBuf: body length exceeds maximum allowed size: " << body_len 
                  << " > " << (MAX_LENGTH - HEAD_TOTAL_LEN) << std::endl;
        throw std::invalid_argument("DataBuf: body length exceeds MAX_LENGTH");
    }
    _buf = std::make_unique<char[]>(_total_len + 1); // 多分配1字节以保证末尾安全
    std::memset(_buf.get(), 0, _total_len + 1);  // 初始化缓冲区为0
}

DataBuf::DataBuf(uint16_t msg_type, const std::string& body)
    : _msg_type(msg_type), _offset(0) {
    // 严格检查消息体长度，确保不超过最大限制
    if (body.size() > MAX_LENGTH - HEAD_TOTAL_LEN) {
        std::cerr << "DataBuf: body length exceeds maximum allowed size: " << body.size() 
                  << " > " << (MAX_LENGTH - HEAD_TOTAL_LEN) << std::endl;
        throw std::invalid_argument("DataBuf: body length exceeds MAX_LENGTH");
    }
    
    _total_len = HEAD_TOTAL_LEN + body.size();
    _buf = std::make_unique<char[]>(_total_len + 1);
    std::memset(_buf.get(), 0, _total_len + 1);
    
    // 网络字节序转换（主机字节序 -> 网络字节序）
    uint16_t net_type = htons(msg_type);
    uint16_t net_len = htons(static_cast<uint16_t>(body.size()));
    
    // 填充头部和数据
    std::memcpy(_buf.get(), &net_type, 2);                // 消息类型（2字节）
    std::memcpy(_buf.get() + 2, &net_len, 2);             // 消息长度（2字节）
    std::memcpy(_buf.get() + HEAD_TOTAL_LEN, body.data(), body.size());  // 消息体
}

DataBuf::~DataBuf() {
    // 智能指针会自动释放内存，无需手动操作
}

Session::Session(int fd, std::shared_ptr<IOThread>io_thread)
    : _fd(fd), _io_thread(std::move(io_thread)),
        _recv_stage(RecvStage::NO_RECV), _send_stage(SendStage::NO_SEND),
        _head_buf(std::make_unique<HeadBuf>(HEAD_TOTAL_LEN)),
        _last_active_time(std::chrono::steady_clock::now()) {
    // 设置Socket为非阻塞（IO线程Epoll需要）
    int flags = fcntl(_fd, F_GETFL, 0);
    if (flags == -1 || fcntl(_fd, F_SETFL, flags | O_NONBLOCK) == -1) {
        throw std::system_error(errno, std::system_category(), "Session: set non-block failed");
    }
    //update_active_time(); 
}

Session::~Session() {
    if (_fd != -1) {
        close(_fd); // 关闭Socket
        _fd = -1;
    }
}

// 对外发送接口（投递到IO线程）
void Session::Send(const std::string& data, size_t msg_type) {
    _io_thread->enqueue_send_data(_fd, data, msg_type);
}
// 解析头部：从HeadBuf提取消息ID和体长度，创建BodyBuf
bool Session::ParseHead() {

    if (!_head_buf) {
        std::cerr << "Session[" << _fd << "]: ParseHead failed - _head_buf is uninitialized (nullptr)" << std::endl;
        return false;
    }
    if (_head_buf->_offset != HEAD_TOTAL_LEN) {
        std::cerr << "Session[" << _fd << "]: ParseHead failed - head not fully received "
                  << "(got=" << _head_buf->_offset << ", expected=" << HEAD_TOTAL_LEN << ")" << std::endl;
        return false;
    }

    // 解析头部（网络字节序转主机字节序）
    uint16_t net_msg_id = 0;
    uint16_t net_body_len = 0;

    if (!_head_buf->_buf) {
        std::cerr << "Session[" << _fd << "]: ParseHead failed - _head_buf->_buf is null (invalid buffer)" << std::endl;
        return false;
    }

    // 消息ID：头部前2字节
    std::memcpy(&net_msg_id, _head_buf->_buf.get(), sizeof(net_msg_id));
    // 消息体长度：头部后2字节（偏移2字节）
    std::memcpy(&net_body_len, _head_buf->_buf.get() + sizeof(net_msg_id), sizeof(net_body_len));
    size_t msg_id = ntohs(net_msg_id);
    size_t body_len = ntohs(net_body_len);
    std::cout << "Session[" << _fd << "]: parsed head - msg_id=" << msg_id 
          << ", body_len=" << body_len << std::endl;
    
    if (msg_id <= 0) {
        std::cerr << "Session[" << _fd << "]: ParseHead failed - invalid msg_id (must be >0) "
                  << "(msg_id=" << msg_id << ")" << std::endl;
        return false;
    }
    // 校验合法性（body 长度不应超过 MAX_LENGTH - HEAD_TOTAL_LEN）
    if (body_len > (MAX_LENGTH - HEAD_TOTAL_LEN) || msg_id <= 0) {
        std::cerr << "Session[" << _fd << "]: invalid head (msg_id=" << msg_id 
                  << ", body_len=" << body_len << ")" << std::endl;
        return false;
    }

    // 创建体缓存，切换到接收体状态
    _body_buf = std::make_unique<DataBuf>(static_cast<uint16_t>(msg_id), body_len);
     if (!_body_buf) {
        std::cerr << "Session[" << _fd << "]: ParseHead failed - create DataBuf failed "
                  << "(msg_id=" << msg_id << ", body_len=" << body_len << ")" << std::endl;
        return false;
    }
    _recv_stage = RecvStage::BODY_RECVING;
    std::cout << "Session[" << _fd << "]: ParseHead success - "
              << "msg_id=" << msg_id << ", body_len=" << body_len << ", switch to BODY_RECVING" << std::endl;

    return true;
}

// 接收数据（IO线程调用）
IOStatus Session::RecvData() {
    try {
        ssize_t recv_len = 0;
        char temp_buf[MAX_LENGTH] = {0};
        // 循环读取（处理粘包）
        while (true) {
            recv_len = recv(_fd, temp_buf, MAX_LENGTH, 0);
            if (recv_len < 0) {
                // 非阻塞正常返回（无数据）
                if (errno == EAGAIN || errno == EWOULDBLOCK) {
                    return IO_SUCCESS;
                }
                // 系统中断重试，其他错误返回失败
                else if (errno == EINTR) {
                    continue;
                } else {
                    std::cerr << "Session[" << _fd << "]: recv failed (" 
                              << std::system_category().message(errno) << ")" << std::endl;
                    return IO_ERROR;
                }
            } 
            // 对端关闭连接
            else if (recv_len == 0) {
                std::cerr << "Session[" << _fd << "]: peer closed" << std::endl;
                return IO_ERROR;
            }
            
            update_active_time(); // 更新活动时间！
            // 根据接收状态处理数据
            if (_recv_stage == RecvStage::NO_RECV) {
                _recv_stage = RecvStage::HEAD_RECVING;
            }
            size_t offset = 0;
            // 循环处理当前接收到的所有数据（使用 offset 前进，避免错误修改 recv_len）
            while (offset < static_cast<size_t>(recv_len)) {
                if (_recv_stage == RecvStage::HEAD_RECVING) {
                    // 计算需要拷贝的长度（不超过头部剩余空间）
                    size_t remaining_head = HEAD_TOTAL_LEN - _head_buf->_offset;
                    size_t available = static_cast<size_t>(recv_len) - offset;
                    size_t need_copy = std::min(available, remaining_head);
                    // 拷贝到头部缓存
                    std::memcpy(_head_buf->_buf.get() + _head_buf->_offset, temp_buf + offset, need_copy);
                    _head_buf->_offset += need_copy;
                    offset += need_copy;

                    // 头部接收完成，解析头部
                    if (_head_buf->_offset == HEAD_TOTAL_LEN) {
                        if (!ParseHead()) {
                            return IO_ERROR;
                        }
                    }
                    // 继续处理可能剩余的数据
                    continue;
                }

                if (_recv_stage == RecvStage::BODY_RECVING) {
                    if (!_body_buf) {
                        return IO_ERROR;
                    }
                    size_t remaining_body = _body_buf->_total_len - _body_buf->_offset;
                    size_t available = static_cast<size_t>(recv_len) - offset;
                    // 计算需要拷贝的长度（不超过体剩余空间）
                    size_t need_copy = std::min(available, remaining_body);
                    // 拷贝到体缓存
                    std::memcpy(_body_buf->_buf.get() + _body_buf->_offset, temp_buf + offset, need_copy);
                    _body_buf->_offset += need_copy;
                    offset += need_copy;
    
                // 体接收完成：封装为RecvNode，投递到逻辑层
                if (_body_buf->_offset == _body_buf->_total_len) {
                    try {
                        // 4. 显式指定RecvNode的缓冲区大小，确保内存分配正确
                        std::shared_ptr<RecvNode> recv_node = std::make_shared<RecvNode>(
                            static_cast<uint16_t >(_body_buf->_total_len),
                            static_cast<uint16_t >(_body_buf->_msg_type)
                        );

                        // 5. 检查RecvNode的内部缓冲区是否有效
                        if (!recv_node || !recv_node->_data) {
                            std::cerr << "Session[" << _fd << "]: RecvNode buffer is invalid" << std::endl;
                            return IO_ERROR;
                        }
                        
                        // 6. 安全拷贝数据（限制拷贝长度）
                        std::memcpy(recv_node->_data.get(), _body_buf->_buf.get(), _body_buf->_total_len);
                        recv_node->_cur_len = recv_node->_total_len;

                        // 投递到逻辑系统
                        LogicSystem::GetInstance()->PostMsgToQue(
                            std::make_shared<LogicNode>(shared_from_this(), recv_node)
                        );

                        // 重置状态，准备接收下一条消息
                        _body_buf.reset();
                        _head_buf->clear();
                        _recv_stage = RecvStage::NO_RECV;
                    } catch (const std::bad_alloc& e) {
                        // 捕获内存分配失败的异常
                        std::cerr << "Session[" << _fd << "]: memory allocation failed: " << e.what() << std::endl;
                        return IO_ERROR;
                    } catch (const std::exception& e) {
                        std::cerr << "Session[" << _fd << "]: RecvNode creation failed: " << e.what() << std::endl;
                        return IO_ERROR;
                    }
                }
                    // 如果当前接收到的数据已经处理完，跳出内部循环以继续 recv
                    if (offset >= static_cast<size_t>(recv_len)) {
                        break;
                    }
            }
            }
            
            
        }
    } catch (const std::exception& e) {
        std::cerr << "Session[" << _fd << "]: recv exception (" << e.what() << ")" << std::endl;
        return IO_ERROR;
    }
}

// 发送数据（IO线程调用）
IOStatus Session::SendData(std::shared_ptr<DataBuf> data) {
    std::lock_guard<std::mutex> lock(_send_mtx);
    _send_queue.push(std::move(data));

    // 若当前无发送，启动发送流程
    if (_send_stage == SendStage::NO_SEND) {
        _send_stage = SendStage::SENDING;
    } else {
        return IO_SUCCESS; // 已有发送任务，等待后续处理
    }

    try {
        // 循环发送队列中的数据
        while (!_send_queue.empty()) {
            auto& cur_data = _send_queue.front();
            while (cur_data->_offset < cur_data->_total_len) {
                ssize_t send_len = send(_fd, cur_data->_buf.get() + cur_data->_offset,
                                       cur_data->_total_len - cur_data->_offset, 0);
                if (send_len < 0) {
                    // 缓冲区满，后续重试
                    if (errno == EAGAIN || errno == EWOULDBLOCK) {
                        return IO_EAGAIN;
                    }
                    // 系统中断重试
                    else if (errno == EINTR) {
                        continue;
                    } else {
                        std::cerr << "Session[" << _fd << "]: send failed (" 
                                  << std::system_category().message(errno) << ")" << std::endl;
                        _send_stage = SendStage::NO_SEND;
                        return IO_ERROR;
                    }
                }
                // 对端关闭
                else if (send_len == 0) {
                    std::cerr << "Session[" << _fd << "]: peer closed (send)" << std::endl;
                    _send_stage = SendStage::NO_SEND;
                    return IO_ERROR;
                }

                // 更新已发送偏移
                cur_data->_offset += send_len;
            }

            // 当前数据发送完成，处理下一个
            _send_queue.pop();
        }

        // 所有数据发送完成
        _send_stage = SendStage::NO_SEND;
        return IO_SUCCESS;
    } catch (const std::exception& e) {
        std::cerr << "Session[" << _fd << "]: send exception (" << e.what() << ")" << std::endl;
        _send_stage = SendStage::NO_SEND;
        return IO_ERROR;
    }
}

void Session::update_active_time(){
    _last_active_time = std::chrono::steady_clock::now();
}